package com.idc.common.util;


import java.text.DateFormat;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.time.FastDateFormat;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

public class DateUtil {
    private static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    private static final String ES_INDEX_DATE_FORMAT = "yyyyMMdd";
	// private static SimpleDateFormat defaultDateTimeFormat = new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT);
	// private static SimpleDateFormat defaultDateFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT);

    /**
     * 获取当前时间
     *
     * @return
     */
    public static Date nowTime() {
        return new Date();
    }

    /**
     * 判断当前时间是否在[startTime, endTime]区间，注意时间格式要一致
     *
     * @param nowTime   当前时间
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     * @author jqlin
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

    public static String chineseDate(Date date) {
        DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.DATE_FIELD);
        String s = df.format(date);
        return s;
    }

    public static String formatDateTime(Date date) {
    	return FastDateFormat.getInstance(DEFAULT_DATE_TIME_FORMAT).format(date);
    }

	public static String toString(Date date, String format) {
		return FastDateFormat.getInstance(format).format(date);
	}

	public static Date parseDate(String dateStr, String format) {
		try {
			return FastDateFormat.getInstance(format).parse(dateStr);
		} catch (ParseException e) {
			return null;
		}
	}

	public static String esIndexDate(Date date) {
		return FastDateFormat.getInstance(ES_INDEX_DATE_FORMAT).format(date);
	}

    public static String formatDate(Date date) {
		return FastDateFormat.getInstance(DEFAULT_DATE_FORMAT).format(date);
    }

    public static String esIndexYesterday() {
        Calendar cal=Calendar.getInstance();
        cal.add(Calendar.DATE,-1);
        Date d = cal.getTime();
		// String format = new SimpleDateFormat(DEFAULT_DATE_FORMAT).format(d);
		return FastDateFormat.getInstance(ES_INDEX_DATE_FORMAT).format(d);
    }
    public static String getYesterday() {
        Calendar cal=Calendar.getInstance();
        cal.add(Calendar.DATE,-1);
        Date d = cal.getTime();
		String format = FastDateFormat.getInstance(DEFAULT_DATE_FORMAT).format(d);
        return format;
    }
    public static Date getYesterdayDate() {
        Calendar cal=Calendar.getInstance();
        cal.add(Calendar.DATE,-1);
        Date d = cal.getTime();
        return d;
    }
    public static Date getYesterdayStart() {
        Calendar cal=Calendar.getInstance();
        cal.add(Calendar.DATE,-1);
        cal.set(Calendar.HOUR_OF_DAY,0);
        cal.set(Calendar.MINUTE,0);
        cal.set(Calendar.SECOND,0);
		cal.set(Calendar.MILLISECOND, 0);
        Date d = cal.getTime();
        return d;
    }

	private static final long DEFAULT_TIME_ZONE_RAW_OFFSET = TimeZone.getDefault().getRawOffset();

	// 获取今日零点毫秒数
	public static long getTodayTimeMillis() {
		long now = System.currentTimeMillis();
		return now - (now + DEFAULT_TIME_ZONE_RAW_OFFSET) % (1000 * 3600 * 24);
	}

	// 获取当日零点毫秒数
	public static long getDateTimeMillis(long timeMillis) {
		return timeMillis - (timeMillis + DEFAULT_TIME_ZONE_RAW_OFFSET) % (1000 * 3600 * 24);
	}

	private static volatile Map<String, DateStamp> todayMap = new ConcurrentHashMap<String, DateStamp>();

	@Data
	@NoArgsConstructor
	@AllArgsConstructor
	public static class DateStamp {
		private long time;
		private String dateString;
	}

	public static String getToday() {
		return getToday(DEFAULT_DATE_FORMAT);
	}

	public static DateStamp getTodayDateStamp() {
		return getTodayDateStamp(DEFAULT_DATE_FORMAT);
	}

	public static String getToday(String format) {
		long today = getTodayTimeMillis();
		DateStamp dateStamp = todayMap.get(format);
		if (null != dateStamp && dateStamp.getTime() == today) {
			return dateStamp.getDateString();
		} else {
			String dateString = toString(new Date(today), format);
			if (null != dateString) {
				todayMap.put(format, new DateStamp(today, dateString));
			}
			return dateString;
		}
	}

	public static DateStamp getTodayDateStamp(String format) {
		long today = getTodayTimeMillis();
		DateStamp dateStamp = todayMap.get(format);
		if (null != dateStamp && dateStamp.getTime() == today) {
			return dateStamp;
		} else {
			String dateString = toString(new Date(today), format);
			if (null != dateString) {
				dateStamp = new DateStamp(today, dateString);
				todayMap.put(format, new DateStamp(today, dateString));
			}
			return dateStamp;
		}
	}

}
